/*
****************************************************************************************
* @FilePath     : platform_uart.c
* @brief        :
* @author       : L0131 - guomingpeng 952856693@qq.com
* @attention    : Copyright (c) 2024 awptech.co.ltd. All rights reserved.
****************************************************************************************
*/
#include "bsp_uart.h"
// #include "op_err_no.h"

static plf_uart_t plf_uart3;

#define BUFFER_SIZE 512
uint8_t uart_buffer[BUFFER_SIZE];
uint32_t last_cndtr = BUFFER_SIZE; // 记录上次的CNDTR值

volatile uint8_t plf_uart3_rx_buf[BUFFER_SIZE] = {0};

int32_t plf_uart3_init(void)
{
    int32_t ret = 0;

    plf_uart3.buf = &plf_uart3_rx_buf;
    plf_uart3.last_cndtr = BUFFER_SIZE; // 记录上次的CNDTR值
    plf_uart3.buf_index = 0;
    plf_uart3.recv_len = 0;
    plf_uart3.recv_callback = NULL;
    // __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);

    return ret;
}

int32_t plf_uart3_deinit(void)
{
    int32_t ret = 0;

    plf_uart3.recv_len = 0;
    plf_uart3.recv_callback = NULL;
    // __HAL_UART_DISABLE_IT(&huart3, UART_IT_IDLE);

    return ret;
}

/* 使用阻塞发送 */
int32_t plf_uart3_send_sync(uint8_t *p_data, uint16_t length)
{
    int32_t ret = 0;
    uint32_t tickstart = HAL_GetTick();

#if 0
    if (HAL_UART_Transmit_DMA(&huart3, p_data, length) == HAL_OK)
    {
        ret = 0;
    }
    else
    {
        ret = -1;
    }

    // 等待DMA传输完成
    while (__HAL_DMA_GET_COUNTER(huart3.hdmatx) != 0)
    {
        if (HAL_GetTick() - tickstart > 10000) 
        {
            ret = -2;
            break;
        }
    }
#else
    HAL_UART_Transmit(&huart3, p_data, length, 0xFFFF);
#endif

    return ret;
}

/* 使用阻塞接收 */
int32_t plf_uart3_recv_sync(uint8_t *p_data, uint16_t length)
{
    int32_t ret = 0;
    HAL_StatusTypeDef hal_ret;

    hal_ret = HAL_UART_Receive(&huart3, p_data, length, 10000);
    if (hal_ret == HAL_OK)
    {
        ret = 0;
    }
    else if (hal_ret == HAL_TIMEOUT)
    {
        ret = -2;
    }
    else
    {
        ret = -1;
    }

    return ret;
}

/* 使用DMA发送 */
int32_t plf_uart3_send_async(uint8_t *p_data, uint16_t length)
{
    int32_t ret = 0;

    if (HAL_UART_Transmit_DMA(&huart3, p_data, length) == HAL_OK)
    {
        ret = 0;
    }
    else
    {
        ret = -1;
    }

    return ret;
}

/* 使用DMA接收 */
int32_t plf_uart3_recv_async(uint8_t *p_data, uint16_t length)
{
    int32_t ret = 0;

    plf_uart3.recv_len = length;
    // if (HAL_UART_Receive_DMA(&huart3, p_data, plf_uart3.recv_len) == HAL_OK)
    // {
    //     ret = 0;
    // }
    // else
    // {
    //     ret = -1;
    // }
    if (HAL_UARTEx_ReceiveToIdle_DMA(&huart3, plf_uart3.buf, sizeof(plf_uart3_rx_buf)) == HAL_OK)
    {
        ret = 0;
    }
    else
    {
        ret = -1;
    }

    return ret;
}

/* 注册回调函数 */
int32_t plf_uart3_recv_callback_register(void *func)
{
    int32_t ret = 0;

    if (func)
    {
        plf_uart3.recv_callback = (recv_callback)func;
    }
    else
    {
        ret = -1;
    }

    return ret;
}

/*
****************************************************************************************
* @description: 串口空闲中断处理函数
* @param {UART_HandleTypeDef} *huart
* @return {*}
****************************************************************************************
*/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if (huart->Instance == USART3)
    {
        uint32_t current_cndtr = __HAL_DMA_GET_COUNTER(huart->hdmarx); // 剩余未使用buffer长度
        uint32_t dma_ptr;
        uint32_t actual_size; // 计算实际接收长度（避免使用Size参数）

        if (current_cndtr < plf_uart3.last_cndtr)
        {
            actual_size = plf_uart3.last_cndtr - current_cndtr; // 正常情况
        }
        else
        {
            actual_size = plf_uart3.last_cndtr + (BUFFER_SIZE - current_cndtr); // 发生循环覆盖
        }

        // 计算DMA当前写入位置（即数据末尾）
        dma_ptr = BUFFER_SIZE - current_cndtr;

        // 处理数据（环形缓冲区逻辑）
        if (actual_size <= dma_ptr)
        {
            // 数据没有环绕，连续存储在缓冲区末尾
            SCB_InvalidateDCache_by_Addr((uint32_t *)&plf_uart3.buf[dma_ptr - actual_size], actual_size);
            if (plf_uart3.recv_callback)
            {
                plf_uart3.recv_callback(&plf_uart3.buf[dma_ptr - actual_size], actual_size);
            }
        }
        else
        {
            // 数据环绕到缓冲区开头
            uint32_t part1_size = plf_uart3.last_cndtr;
            uint32_t part2_size = dma_ptr;

            // 处理末尾部分
            SCB_InvalidateDCache_by_Addr((uint32_t *)&plf_uart3.buf[BUFFER_SIZE - part1_size], part1_size);
            if (plf_uart3.recv_callback)
            {
                plf_uart3.recv_callback(&plf_uart3.buf[BUFFER_SIZE - part1_size], part1_size);
            }

            // 处理开头部分
            SCB_InvalidateDCache_by_Addr((uint32_t *)&plf_uart3.buf[part2_size], part2_size);
            if (plf_uart3.recv_callback)
            {
                plf_uart3.recv_callback(&plf_uart3.buf[part2_size], part2_size);
            }
        }
        plf_uart3.last_cndtr = current_cndtr;
    }
}

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART3)
    {
        __HAL_UNLOCK(huart);
        __HAL_UART_CLEAR_PEFLAG(huart);
        __HAL_UART_CLEAR_FEFLAG(huart);
        __HAL_UART_CLEAR_NEFLAG(huart);
        __HAL_UART_CLEAR_OREFLAG(huart);
        __HAL_UART_CLEAR_IDLEFLAG(huart);
        HAL_UARTEx_ReceiveToIdle_DMA(&huart3, plf_uart3.buf, sizeof(plf_uart3_rx_buf));
    }
}
